#if UNITY_EDITOR && HybridCLR

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSimpleJSON;
using CSUtils;
using HybridCLR.Editor;
using HybridCLR.Editor.Settings;
using U3dUtils;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace AppScript.Editor {
    public class Editor_HybridCLR {
        const string _tag = "Editor_HybridCLR";

        [MenuItem("HybridCLR/dll.拷贝.热更新/热更新dll列表排序")]
        static void ssss() {
            CLogCat.GetInstance().Init(true, true);
            CAssemblyDef.Init();

            var arr = HybridCLRSettings.Instance.hotUpdateAssemblyDefinitions;
            var orderByList = OrderBy();
            arr = orderByList.Select(n=>n.ass).ToArray();
            HybridCLRSettings.Instance.hotUpdateAssemblyDefinitions = arr;

            var ssb = new StringBuilder();
            ssb.AppendLine($" ");
            for(int i = 0; i < arr.Length; i++) {
                ssb.AppendLine($"{arr[i].name} ");
            }
            Debug.LogError($"程序集名称......{ssb}");
        }

        static List<CAssemblyDef> OrderBy() {
            var orderByList = new List<CAssemblyDef>();
            var orderByDic = new Dictionary<string, CAssemblyDef>();
            var noOrderByDic = new Dictionary<string, CAssemblyDef>();
            noOrderByDic.SetAddDic(CAssemblyDef.name_allFixDic);
            int depth = 0;
            while(noOrderByDic.Count > 0) {
                var arr = noOrderByDic.Values.ToArray();
                for(int i2 = 0; i2 < arr.Length; i2++) {
                    var assd = arr[i2];
                    if(assd.refName_refParentDic.Count == 0) {
                        orderByList.Add(assd);
                        orderByDic[assd.name] = assd;
                        noOrderByDic.Remove(assd.name);
                    }
                }
                arr = noOrderByDic.Values.ToArray();
                for(int i2 = 0; i2 < arr.Length; i2++) {
                    var assd = arr[i2];
                    var _arr = assd.refName_refParentDic.Values.ToArray();
                    for(int i4 = 0; i4 < _arr.Length; i4++) {
                        var parentAssd = _arr[i4];
                        if(parentAssd.isHotFix == false) {
                            assd.refName_refParentDic.Remove(parentAssd.name);
                        } else if(orderByDic.ContainsKey(parentAssd.name)) {
                            assd.refName_refParentDic.Remove(parentAssd.name);
                        }
                    }
                }
                CLog.E(_tag, $"循环次数.......{depth}....{noOrderByDic.Count}/{noOrderByDic.ToStr(n=>n.Key)}");
                depth++;
                if(depth > 1000) {
                    break;
                }
            }
            return orderByList;
        }

        [MenuItem("HybridCLR/dll.拷贝.热更新/热更新dll..检查关联")]
        public static void Swww() {
            CLogCat.GetInstance().Init(true, true);
            CAssemblyDef.Init();

            var hotFixDic = new Dictionary<string, CAssemblyDef>();
            var noHotFixDic = new Dictionary<string, CAssemblyDef>();
            noHotFixDic.SetAddDic(CAssemblyDef.name_allFixDic);

            var arr = HybridCLRSettings.Instance.hotUpdateAssemblyDefinitions;
            for(int i2 = 0; i2 < arr.Length; i2++) {
                var ass = arr[i2];
                //Debug.Log($"检查.....{i2}......{ass.name}");
                var asst = noHotFixDic[ass.name];
                hotFixDic[ass.name] = asst;
                noHotFixDic.Remove(ass.name);
            }
            Debug.LogError($"检查.....开始");
            int count = 0;
            foreach(var kv in noHotFixDic) {
                var asst = kv.Value;
                foreach(var kv2 in asst.refName_refParentDic) {
                    if(hotFixDic.ContainsKey(kv2.Key)) {
                        Debug.LogError($"超级错误..非热更引用热更.....{count++}.....{asst}.==>.{kv2.Key}");
                    }
                }
            }
            Debug.LogError($"检查.....结束");
        }

        static void _LoadAllDll() {
            var allArr = AssetDatabase.GetAllAssetPaths();
            var list = new List<AssemblyDefinitionAsset>();
            for(int i2 = 0; i2 < allArr.Length; i2++) {
                var path = allArr[i2];
                if(path.EndsWith(".asmdef", StringComparison.Ordinal)) {
                    var assd = AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(path);
                    list.Add(assd);
                }
            }
            CAssemblyDef.Parse(list.ToArray(), false);
        }

        class CAssemblyDef {
            public string name=>ass.name;
            public AssemblyDefinitionAsset ass;
            public bool isHotFix {get;set;}
            public Dictionary<string, CAssemblyDef> refName_refParentDic = new Dictionary<string, CAssemblyDef>();
            public Dictionary<string, CAssemblyDef> refName_refSubDic = new Dictionary<string, CAssemblyDef>();
            public static Dictionary<string, CAssemblyDef> name_allFixDic = new Dictionary<string, CAssemblyDef>();
            public static Dictionary<string, CAssemblyDef> name_allDic = new Dictionary<string, CAssemblyDef>();

            public static void Init() {
                CAssemblyDef.name_allDic.Clear();
                CAssemblyDef.name_allFixDic.Clear();

                var asmdefArr = AssetDatabase.FindAssets("t:asmdef");
                for(int i2 = 0; i2 < asmdefArr.Length; i2++) {
                    var assetPath = AssetDatabase.GUIDToAssetPath(asmdefArr[i2]);
                    var ass = AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(assetPath);
                    new CAssemblyDef(ass, false);
                }

                var arr = HybridCLRSettings.Instance.hotUpdateAssemblyDefinitions;
                CAssemblyDef.Parse(arr, true);

                Debug.LogError($"程序集名称..");
            }

            public static void Parse(AssemblyDefinitionAsset[] arr, bool isHotFix) {
                for(int i2 = 0; i2 < arr.Length; i2++) {
                    var ass = arr[i2];
                    if(isHotFix) {
                        if(name_allDic.ContainsKey(ass.name)) {
                            var ass2 = name_allDic[ass.name];
                            ass2.isHotFix = true;
                            name_allFixDic[ass2.name] = ass2;
                        } else {
                            CLog.Ex(_tag, $"错误......热更新dll不在全部dll集合当中.....{ass.name}");
                        }
                    } else {
                        name_allDic[ass.name] = new CAssemblyDef(ass, isHotFix);
                    }
                    //var na = new CAssemblyDef(arr[i2], isHotFix);
                }
                foreach(var kv in name_allFixDic) {
                    kv.Value.ChechAddDef();
                }
            }

            public CAssemblyDef(AssemblyDefinitionAsset ada, bool isHotFix) {
                this.ass = ada;
                if(isHotFix) {
                    name_allFixDic[name] = this;
                }
                name_allDic[name] = this;
                Debug.Log($"加载.asmdef....{this}");
                Parse(ada, isHotFix);
            }

            void Parse(AssemblyDefinitionAsset ada, bool isHotFix) {
                var node = JSON.Parse(ada.text);
                var arr = node["references"].AsArray;
                for(int i2 = 0; i2 < arr.Count; i2++) {
                    var name = arr[i2];
                    if(name.Count > 20) {
                        Debug.LogError($"程序集名称......{name}");
                    }
                    refName_refParentDic[name] = null;
                }
            }

            void ChechAddDef() {
                var arr = refName_refParentDic.Keys.ToArray();
                for(int i3 = 0; i3 < arr.Length; i3++) {
                    var parentName = arr[i3];
                    if(name_allDic.ContainsKey(parentName) == false) {
                        Debug.Log($"超级错误..未添加的dll......{this}.==>.{parentName}");
                        refName_refParentDic.Remove(parentName);
                        continue;
                    }
                    var assd = name_allDic[parentName];
                    refName_refParentDic[parentName] = assd;
                    assd.refName_refSubDic[name] = this;
                }

                foreach(var kv in name_allDic) {
                    var _ass = kv.Value;
                    if(_ass.isHotFix == false) {
                        foreach(var kv2 in _ass.refName_refParentDic) {
                            var _ass2 = kv2.Value;
                            if(_ass2 == null) {
                                Debug.Log($"超级错误..未知的引用.....{_ass}.==>.null");
                            } else if(_ass2.isHotFix) {
                                Debug.LogError($"超级错误..非热更新dll...不能引用热更新dll.....{_ass}.==>.{_ass2}");
                            }
                        }
                    }
                }
            }

            public override string ToString()=>name;
        }
        #if XPBuild
        [MenuItem("HybridCLR/dll.拷贝.热更新/拷贝..AOTMeta")]
        static void sssss() {
            var cfg = BuildAppCfg.Instance;
            cfg.LoadData();
            Editor_ProjectBuild.Huatuo_CopyAOTMeta(EditorUserBuildSettings.activeBuildTarget);
        }
        #endif
    }
}

#endif
